//package org.bdware.doip.implementation;
//
//import com.google.gson.JsonObject;
//import com.google.gson.JsonParser;
//import org.apache.http.HttpHost;
//import org.apache.log4j.Logger;
//import org.bdware.doip.core.model.digitalObject.DigitalObject;
//import org.bdware.doip.core.model.metadata.SearchParameter;
//import org.bdware.doip.core.model.metadata.SearchResult;
//import org.bdware.doip.core.utils.DoipGson;
//import org.elasticsearch.action.DocWriteResponse;
//import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
//import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
//import org.elasticsearch.action.delete.DeleteRequest;
//import org.elasticsearch.action.index.IndexRequest;
//import org.elasticsearch.action.index.IndexResponse;
//import org.elasticsearch.action.search.SearchRequest;
//import org.elasticsearch.action.search.SearchResponse;
//import org.elasticsearch.action.search.SearchType;
//import org.elasticsearch.client.RequestOptions;
//import org.elasticsearch.client.RestClient;
//import org.elasticsearch.client.RestHighLevelClient;
//import org.elasticsearch.client.core.MainResponse;
//import org.elasticsearch.client.indices.GetIndexRequest;
//import org.elasticsearch.common.xcontent.XContentType;
//import org.elasticsearch.index.query.QueryBuilder;
//import org.elasticsearch.index.query.QueryBuilders;
//import org.elasticsearch.search.SearchHit;
//import org.elasticsearch.search.builder.SearchSourceBuilder;
//import org.elasticsearch.search.sort.SortOrder;
//
//import java.io.IOException;
//import java.net.URI;
//import java.net.URISyntaxException;
//import java.util.Arrays;
//
//public class DoIndexerESImpl implements DoIndexer{
//    public RestHighLevelClient client;
//    public String indexName;
//    public RequestOptions requestOptions;
//    public IndexRequest request;
//
//    Logger logger = Logger.getLogger(DoIndexerESImpl.class);
//
//    public DoIndexerESImpl(String indexName, String url) throws URISyntaxException {
//        URI uri = new URI(url);
//        this.client = new RestHighLevelClient(RestClient.builder(new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme())));
//        this.indexName = indexName;
//        this.requestOptions = RequestOptions.DEFAULT;
//        this.request = new IndexRequest(indexName);
//        try {
//            MainResponse response = client.info(requestOptions);
//            String version = response.getVersion().getNumber();
//            logger.debug("target es version: "+ version);
//            GetIndexRequest request = new GetIndexRequest(indexName);
//            if (!client.indices().exists(request, requestOptions)) {
//                initializeIndex();
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
//
//    @Override
//    public boolean indexDigitalObject(DigitalObject doc) throws IOException {
//        String json = DoipGson.getDoipGson().toJson(doc);
//        request.id(doc.id);
//        request.type("_doc");
//        request.source(json, XContentType.JSON);
//        IndexResponse indexResponse = client.index(request, requestOptions);
//        return indexResponse.getResult().equals(DocWriteResponse.Result.CREATED);
//    }
//
//    @Override
//    public boolean indexJson(String handle, String doc) throws IOException {
//        String json = doc;
//        request.id(handle);
//        request.type("_doc");
//        request.source(json, XContentType.JSON);
//        IndexResponse indexResponse = client.index(request, requestOptions);
//        return indexResponse.getResult().equals(DocWriteResponse.Result.CREATED);
//    }
//
//    public SearchResult search(SearchParameter searchParameter) throws IOException {
//        if(searchParameter == null) {
//            searchParameter = SearchParameter.getDefaultParameter();
//        }
//        int from;
//        int size = searchParameter.pageSize;
//        if (searchParameter.pageNum == 0 || searchParameter.pageSize <= 0) {
//            from = 0;
//        } else {
//            from = searchParameter.pageNum * searchParameter.pageSize;
//        }
//
//        if (searchParameter.pageSize < 0) {
//            size = 500;
//        }
//
//        QueryBuilder queryBuilder = QueryBuilders.queryStringQuery(searchParameter.query);
//        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//        searchSourceBuilder
//                .query(queryBuilder)
//                .from(from)
//                .trackTotalHits(true)
//                .explain(false)
//                .size(size);
//
//        // if type is specified, return fetch id only
//        if (searchParameter.type.equals("id")) {
//            searchSourceBuilder.fetchSource(false);
//        } else {
//            searchSourceBuilder.fetchSource(true);
//        }
//
//        searchSourceBuilder.storedFields(Arrays.asList("type.raw", "type"));
//
//        for (int i=0;i<searchParameter.sortFields.size();i++) {
//            /*
//            SearchParameter.SortField sortField = searchParameter.sortFields.get(i);
//            if (sortField.order.equals("asc")) {
//                searchSourceBuilder.sort(sortField.item, SortOrder.ASC);
//                logger.info("add asc sort field: " + sortField.item);
//            } else {
//                searchSourceBuilder.sort(sortField.item, SortOrder.DESC);
//                logger.info("add desc sort field: " + sortField.item);
//            }
//             */
//            // TODO: support any field search (need to config es mapping)
//            searchSourceBuilder.sort("_id", SortOrder.DESC);
//            break;
//        }
//
//        SearchRequest request = new SearchRequest(indexName);
//        request.searchType(SearchType.DFS_QUERY_THEN_FETCH);
//        request.source(searchSourceBuilder);
//
//        SearchResponse searchResponse = client.search(request, requestOptions);
//        logger.info("search response: " + searchResponse.toString());
//        SearchHit[] hits = searchResponse.getInternalResponse().hits().getHits();
//        SearchResult searchResult = new SearchResult();
//        searchResult.size = hits.length;
//        logger.info("hits size:" +  hits.length);
//        for (SearchHit hit :hits) {
//            logger.info("search res docid:" + hit.getId());
//            String tmp = hit.getSourceAsString();
//            if (tmp == null) {
//                tmp = hit.getId();
//                searchResult.addItem(tmp);
//            } else {
//                JsonObject jsonObject = JsonParser.parseString(tmp).getAsJsonObject();
//                searchResult.addItem(jsonObject);
//            }
//        }
//        return searchResult;
//    }
//
//    public boolean deleteDigitalObject(String id) {
//        DeleteRequest deleteRequest = new DeleteRequest(indexName);
//        deleteRequest.id(id);
//        deleteRequest.type("_doc");
//        try {
//            client.delete(deleteRequest, requestOptions);
//        } catch (Exception e) {
//            logger.error("error on deleting digital object");
//            e.printStackTrace();
//            return false;
//        }
//        return true;
//    }
//
//    private void initializeIndex() throws IOException {
//        logger.info("Initializing Elasticsearch index.");
//        CreateIndexRequest request = new CreateIndexRequest(indexName);
//        CreateIndexResponse response = client.indices().create(request, requestOptions);
//        if (!response.isAcknowledged()) {
//            logger.error("Create index response not acknowledged.");
//        } else {
//            logger.info("Create index response: acknowledged.");
//        }
//    }
//}
